/* * Copyright 2001-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jvnet.maven.jellydoc; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.AbstractArtifactResolutionException; import org.apache.maven.artifact.resolver.ArtifactResolver; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojoExecutionException; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectHelper; import org.apache.maven.reporting.MavenReport; import org.apache.maven.reporting.MavenReportException; import org.apache.tools.ant.DefaultLogger; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.Javadoc; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.codehaus.doxia.sink.Sink; import org.codehaus.plexus.util.FileUtils; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.tree.DefaultDocument; import org.dom4j.io.DocumentSource; import org.dom4j.io.SAXReader; import javax.xml.transform.Templates; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import java.io.File; import java.io.IOException; import java.io.FileOutputStream; import java.io.FileNotFoundException; import java.net.MalformedURLException; import java.util.Collection; import java.util.List; import java.util.Locale; /** * Generates jellydoc XML and other artifacts from there. * * @author Kohsuke Kawaguchi * @goal jellydoc * @phase generate-sources * @requiresDependencyResolution compile */ @SuppressWarnings({"unchecked"}) public class JellydocMojo extends AbstractMojo implements MavenReport { /** * The Maven Project Object * * @parameter expression="${project}" * @required * @readonly */ public MavenProject project; /** * The plugin dependencies. * * @parameter expression="${plugin.artifacts}" * @required * @readonly */ public List<Artifact> pluginArtifacts; /** * Version of this plugin. * * @parameter expression="${plugin.version}" * @required * @readonly */ public String pluginVersion; /** * Factory for creating artifact objects * * @component */ public ArtifactFactory factory; /** * Used for resolving artifacts * * @component */ public ArtifactResolver resolver; /** * The local repository where the artifacts are located. * * @parameter expression="${localRepository}" */ public ArtifactRepository localRepository; /** * @component */ public MavenProjectHelper helper; private File outputDirectory; public void execute() throws MojoExecutionException, MojoFailureException { Project p = new Project(); DefaultLogger logger = new DefaultLogger(); logger.setErrorPrintStream(System.err); logger.setOutputPrintStream(System.out); logger.setMessageOutputLevel( getLog().isDebugEnabled() ? Project.MSG_DEBUG : Project.MSG_INFO ); p.addBuildListener(logger); Javadoc javadoc = new Javadoc(); javadoc.setTaskName("jellydoc"); javadoc.setProject(p); for (Object dir : project.getCompileSourceRoots()) { FileSet fs = new FileSet(); fs.setProject(p); fs.setDir(new File(dir.toString())); javadoc.addFileset(fs); } javadoc.setClasspath(makePath(p,(Collection<Artifact>)project.getArtifacts())); Javadoc.DocletInfo d = javadoc.createDoclet(); d.setProject(p); d.setName(TagXMLDoclet.class.getName()); setParam(d, "-d", targetDir().getAbsolutePath()); Path docletPath = makePath(p, pluginArtifacts); try { Artifact self = factory.createArtifact("org.jvnet.maven-jellydoc-plugin", "maven-jellydoc-plugin", pluginVersion, null, "maven-plugin"); resolver.resolve(self,project.getPluginArtifactRepositories(),localRepository); docletPath.createPathElement().setLocation(self.getFile()); } catch (AbstractArtifactResolutionException e) { throw new MojoExecutionException("Failed to resolve plugin from within itself",e); } d.setPath(docletPath); // debug support // javadoc.createArg().setLine("-J-Xrunjdwp:transport=dt_socket,server=y,address=8000"); javadoc.execute(); generateSchema(); } public void generateSchema() throws MojoExecutionException { try { getLog().info("Generating XML Schema"); TransformerFactory tf = TransformerFactory.newInstance(); Templates templates = tf.newTemplates(new StreamSource(JellydocMojo.class.getResource("xsdgen.xsl").toExternalForm())); File source = new File(project.getBasedir(), "target/taglib.xml"); for(Element lib : (List<Element>)new SAXReader().read(source).selectNodes("/tags/library")) { String prefix = lib.attributeValue("prefix"); File schema = new File(project.getBasedir(), "target/taglib-"+prefix+".xsd"); lib.getParent().remove(lib); // make it on its own DefaultDocument newDoc = new DefaultDocument(); newDoc.setRootElement(lib); templates.newTransformer().transform( new DocumentSource(newDoc), new StreamResult(new FileOutputStream(schema))); helper.attachArtifact(project,"xsd","taglib-"+prefix,schema); } } catch (TransformerException e) { throw new MojoExecutionException("Failed to generate schema",e); } catch (DocumentException e) { throw new MojoExecutionException("Failed to generate schema",e); } catch (FileNotFoundException e) { throw new MojoExecutionException("Failed to generate schema",e); } } private Path makePath(Project p, Collection<Artifact> artifacts) { Path docletPath = new Path(p); for (Artifact artifact : artifacts) docletPath.createPathElement().setLocation(artifact.getFile()); return docletPath; } private File targetDir() { return new File(project.getBasedir(),"target"); } private void setParam(Javadoc.DocletInfo d, String name, String value) { Javadoc.DocletParam dp = d.createParam(); dp.setName(name); dp.setValue(value); } // private Path makePath(Project p, List list) { // Path src = new Path(p); // for (Object dir : list) // src.createPathElement().setLocation(new File(dir.toString())); // return src; // } public void generate(Sink sink, Locale locale) throws MavenReportException { try { execute(); new ReferenceRenderer(sink,new File(targetDir(),"taglib.xml").toURI().toURL()).render(); FileUtils.copyDirectory(targetDir(),new File(targetDir(),"site"),"taglib-*.xsd",null); } catch (AbstractMojoExecutionException e) { throw new MavenReportException("Failed to generate report",e); } catch (MalformedURLException e) { throw new MavenReportException("Failed to generate report",e); } catch (DocumentException e) { throw new MavenReportException("Failed to generate report",e); } catch (IOException e) { throw new MavenReportException("Failed to generate report",e); } } public String getOutputName() { return "jelly-taglib-ref"; } public String getName(Locale locale) { return "Jelly taglib reference"; } public String getCategoryName() { return CATEGORY_PROJECT_REPORTS; } public String getDescription(Locale locale) { return "Jelly taglib reference"; } public void setReportOutputDirectory(File outputDirectory) { this.outputDirectory = outputDirectory; } public File getReportOutputDirectory() { return this.outputDirectory; } public boolean isExternalReport() { return false; } public boolean canGenerateReport() { // TODO: check if the current project has any source files return true; } }